﻿using GKQC.Common;
using GKQC.DbHelper.Dao;
using GKQC.DbHelper.DbModels;
using GKQC.DbHelper.ViewModels;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GKQC.DbHelper.Services
{
    public class ComService
    {
        AllDbContext dbContext;

        public ComService(AllDbContext dbContext)
        {
            this.dbContext = dbContext;
        }

        public string GetNewLotNo(ComHeadModel head)
        {
            string lotNo = string.Empty;

            string prefix = head.TestDate.ToString("yyyyMMdd");
            string sql = "select max(LotNo) from t_com_head where LotNo like @Prefix";
            var dt = dbContext.QcDb.Ado.GetDataTable(sql, new SugarParameter[]{
              new SugarParameter("@Prefix",prefix+ "%")
            });

            int no = 1;
            if (dt != null && dt.Rows.Count > 0)
            {
                int.TryParse(dt.Rows[0][0].ToString().Replace(prefix, string.Empty), out no);
                lotNo = prefix + (no + 1).ToString().PadLeft(3, '0');
            }

            head.LotNo = lotNo;
            return lotNo;
        }

        public List<ComDtlModel> GetDtls(long headId)
        {
            List <ComDtlModel> dtls =  dbContext.QcDb.Queryable<ComDtlModel>().Where(d => d.HeadId == headId)
                .OrderBy(d => d.SNo, OrderByType.Asc)
                .ToList();
            if (dtls != null)
            {
                foreach(ComDtlModel d in dtls)
                {
                    d.ElectricViewModels = new List<ElectricViewModel>();
                    d.SizeViewModels = new List<SizeViewModel>();
                }
            }
            return dtls;
        }

        public List<ComDataModel> GetDatas(long headId, int sNo)
        {
            return dbContext.QcDb.Queryable<ComDataModel>()
                .Where(d => d.HeadId == headId && d.SNo == sNo)
                .ToList();
        }
        public List<ComDataModel> GetDatas(long headId)
        {
            return dbContext.QcDb.Queryable<ComDataModel>()
                .Where(d => d.HeadId == headId)
                .ToList();
        }

        public List<ComDataModel> GetDatas(ComHeadModel headModel, ComDtlModel dtl)
        {
            if (headModel == null || dtl == null || headModel.Id <= 0 || dtl.SNo <= 0) return null;
            //dtl.CreateSNo(headModel.ElectricQty, headModel.SizeQty, dtl.SNo);
            List<ComDataModel> datas = GetDatas(headModel.Id, dtl.SNo);
            ViewModelTrans<ComDataModel>.DataToView(dtl.SNo, datas, dtl.ElectricViewModels, dtl.SizeViewModels);
            return datas;
        }

        public ComHeadModel GetHeadById(long id)
        {
            var heads = dbContext.QcDb.Queryable<ComHeadModel>().Where(o => o.Id == id);
            if (heads != null && heads.Count() > 0)
                return heads.First();
            else
                return null;
        }

        public List<ComHeadModel> GetHeads(int count)
        {
            return dbContext.QcDb.Queryable<ComHeadModel>()
                .OrderBy(o => o.TestDate, OrderByType.Desc)
                .Take(count).ToList();
        }

        public int Save(ComHeadModel headModel)
        {
            int i = 0;

            bool isNew = false;
            try
            {
                dbContext.QcDb.Ado.BeginTran();
                if (headModel.Id <= 0)
                {
                    if (!dbContext.QcDb.Insertable(headModel).ExecuteCommandIdentityIntoEntity())
                        throw new Exception("U0001: 新增保存出錯");

                    isNew = true;
                }
                if (!isNew)
                    dbContext.QcDb.Deleteable<ComDataModel>()
                        .Where(o => o.HeadId == headModel.Id)
                        .ExecuteCommand();
                if (isNew) headModel.Dtls.ForEach(d => d.HeadId = headModel.Id);
                List<ComDataModel> datas = new List<ComDataModel>();
                if (headModel.Dtls.Count > 0)
                {
                    foreach (ComDtlModel dtl in headModel.Dtls)
                    {
                        dtl.HeadId = headModel.Id;
                        List<ComDataModel> dtl_datas = new List<ComDataModel>();
                        if (dtl.ElectricViewModels != null && dtl.ElectricViewModels.Count > 0)
                        {
                            dtl_datas.AddRange(ViewModelTrans<ComDataModel>.ElectricViewToData(headModel.Id, dtl.SNo, dtl.ElectricViewModels));
                        }
                        if (dtl.SizeViewModels != null && dtl.SizeViewModels.Count > 0)
                        {
                            dtl_datas.AddRange(ViewModelTrans<ComDataModel>.SizeViewToData(headModel.Id, dtl.SNo, dtl.SizeViewModels));
                        }

                        dtl.Datas = dtl_datas;
                        datas.AddRange(dtl_datas);
                    }

                    var overLengths = datas.Where(d => d.Value > 9999999999);
                    if (overLengths != null && overLengths.Count() > 0)
                        overLengths.ToList().ForEach(o => o.Value = 9999999999);
                    var overLengths2 = datas.Where(d => d.Value < -9999999999);
                    if (overLengths2 != null && overLengths2.Count() > 0)
                        overLengths2.ToList().ForEach(o => o.Value = -9999999999);
                }

                List<ComDtlModel> dtls = headModel.Dtls.Where(d => d.Id > 0).ToList();
                if (dtls != null && dtls.Count > 0)
                    dbContext.QcDb.Updateable(dtls)
                        .ExecuteCommand();
                dtls = headModel.Dtls.Where(d => d.Id <= 0).ToList();
                if (dtls != null && dtls.Count > 0)
                    dbContext.QcDb.Insertable(dtls)
                    .ExecuteCommand();
                if (datas.Count > 0)
                    dbContext.QcDb.Insertable(datas)
                    .ExecuteCommand();
                if (!isNew)
                    i = dbContext.QcDb.Updateable(headModel)
                        .ExecuteCommand();
                else
                    i = 1;

                dbContext.QcDb.Ado.CommitTran();
            }
            catch (Exception ex)
            {
                dbContext.QcDb.Ado.RollbackTran();
                Logger.LogError(ex);
                throw ex;
            }
            return i;
        }

        /// <summary>
        /// 複製，不包含檢測數據
        /// </summary>
        /// <param name="ComHeadModel"></param>
        /// <returns></returns>
        public ComHeadModel Clone(ComHeadModel ComHeadModel)
        {
            ComHeadModel newModel;
            if (ComHeadModel == null)
                newModel = new ComHeadModel();
            else newModel = ClassClone<ComHeadModel, ComHeadModel>.Clone(ComHeadModel);
            newModel.Id = 0;
            newModel.ModiDate = null;
            newModel.ModiUser = string.Empty;
            if (newModel.Dtls != null && newModel.Dtls.Count > 0)
            {
                newModel.Dtls = new List<ComDtlModel>();
            }

            return newModel;
        }

        /// <summary>
        /// 審核
        /// </summary>
        /// <param name="ortList"></param>
        /// <returns></returns>
        public int Approve(List<ComHeadModel> ortList)
        {
            int i = 0;
            i = dbContext.QcDb.Updateable(ortList)
                .UpdateColumns(it => new { it.ApproveUser, it.ApproveDate })
                .ExecuteCommand();
            return i;
        }


        /// <summary>
        /// 反審核
        /// </summary>
        /// <param name="headList"></param>
        /// <returns></returns>
        public int UnApprove(List<ComHeadModel> headList)
        {
            int i = 0;
            if (headList != null && headList.Count > 0)
            {
                i = dbContext.QcDb.Updateable(headList)
                    .UpdateColumns(it => new { it.ApproveUser, it.ApproveDate })
                    .ExecuteCommand();
            }
            return i;
        }

        /// <summary>
        /// 刪除
        /// </summary>
        /// <param name="headList"></param>
        /// <returns></returns>
        public int Delete(List<ComHeadModel> headList)
        {
            int i = 0;
            try
            {
                dbContext.QcDb.Ado.BeginTran();
                dbContext.QcDb.Deleteable<ComDataModel>()
                    .In(it => it.HeadId, headList.Select(o => o.Id).ToArray())
                    .ExecuteCommand();
                dbContext.QcDb.Deleteable<ComDtlModel>()
                    .In(it => it.HeadId, headList.Select(o => o.Id).ToArray())
                    .ExecuteCommand();
                i = dbContext.QcDb.Deleteable(headList)
                    .ExecuteCommand();
                dbContext.QcDb.Ado.CommitTran();
            }
            catch(Exception ex)
            {
                dbContext.QcDb.Ado.RollbackTran();
                Logger.LogError(ex);
                throw ex;
            }
            return i;
        }

        public List<ComHeadModel> Query(ComFilter filter)
        {
            if (filter == null) return GetHeads(100);
            return dbContext.QcDb.Queryable<ComHeadModel>()
                .WhereIF(!string.IsNullOrWhiteSpace(filter.LotNo), t => t.LotNo == filter.LotNo)
                .WhereIF(filter.IsModiDate, t => t.ModiDate >= filter.StartModiDate)
                .WhereIF(filter.IsModiDate, t => t.ModiDate < filter.StartModiDate.AddDays(1))
                .WhereIF(!string.IsNullOrWhiteSpace(filter.Series), t => t.Series == filter.Series)
                .WhereIF(!string.IsNullOrWhiteSpace(filter.Spec), t => t.Spec == filter.Spec)
                .WhereIF(!string.IsNullOrWhiteSpace(filter.Size), t => t.Size == filter.Size)
                .WhereIF(filter.IsTestDate, t => t.TestDate >= filter.StartTestDate.Date)
                .WhereIF(filter.IsTestDate, t => t.TestDate < filter.EndTestDate.AddDays(1).Date)
                .WhereIF(filter.IsApprove && !filter.IsUnApprove, t => !SqlFunc.IsNullOrEmpty(t.ApproveUser))
                .WhereIF(!filter.IsApprove && filter.IsUnApprove, t => SqlFunc.IsNullOrEmpty(t.ApproveUser))
                .WhereIF(!string.IsNullOrWhiteSpace(filter.CreateUser), t => t.CreateUser == filter.CreateUser)
                .OrderBy(t=>t.TestDate, OrderByType.Desc)
                .ToList();
        }

        public void GenStandard(ComHeadModel head,ComDtlModel dtl)
        {
            int rowIndex = head.Dtls.IndexOf(dtl);
            try
            {
                if (dtl.SNo == 1)
                {
                    //head.Standard.CapMax = head.Cap * 1.2;
                    //head.Standard.CapMin = head.Cap * 0.8;
                    ////从ERP取值

                    //head.Standard.EsrMax = head.EsrMax;
                    //head.Standard.DfMax = head.DfMax;
                    //head.Standard.EsrMax = head.EsrMax;
                }
                else
                {
                    //head.Standard.CapMax = head.Cap * (1 + (head.CapRate > 0.2 ? head.CapRate : 0.2));
                    //head.Standard.CapMin = head.Cap * (1 - (head.CapRate > 0.2 ? head.CapRate : 0.2));
                    //head.Standard.EsrMax = head.EsrMaxAfter;
                    //head.Standard.DfMax = head.DfMaxAfter;
                    //head.Standard.EsrMax = head.EsrMaxAfter;
                }

                //head.Standard.ZMax = head.ZMax;
                //head.Standard.LcMax = head.LcMax;
            }
            catch(Exception ex)
            {
                Logger.LogError(ex);
                throw ex;
            }
        }
    }
}
